##################################################
# SCIFOR PROJECT
##################################################
CMAKE_MINIMUM_REQUIRED(VERSION 3.0.2)
PROJECT(scifor Fortran)
SET(VERSION 4.1.3)

SET(BUILD_TYPE "RELEASE" CACHE STRING "Build type")
MESSAGE(STATUS "BUILD_TYPE=${BUILD_TYPE}")
SET(CMAKE_BUILD_TYPE ${BUILD_TYPE} CACHE INTERNAL "Build type" FORCE)

# Add our local CMAKE modules to the module path
SET(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/Modules")

INCLUDE(${CMAKE_MODULE_PATH}/ColorsMsg.cmake)

# Check that Fortran 90 is supported
IF(NOT CMAKE_Fortran_COMPILER_SUPPORTS_F90)
   MESSAGE(FATAL_ERROR "Fortran compiler does not support F90")
ENDIF(NOT CMAKE_Fortran_COMPILER_SUPPORTS_F90)

# Set some options the user may choose
OPTION(USE_MPI "Use the MPI library for parallelization" ON)
OPTION(VERBOSE "Build a verbose Makefile" OFF)

# reSet compiler to MPI is required 
IF(USE_MPI)
  FIND_PACKAGE(MPI REQUIRED)
  SET(CMAKE_Fortran_COMPILER ${MPI_Fortran_COMPILER})
  SET(MPI_CPP "MPI")
  MESSAGE(STATUS "${Yellow}Set Fortran compiler FC to ${ColourReset}${CMAKE_Fortran_COMPILER}")
ELSE(USE_MPI)
  SET(MPI_CPP "")
ENDIF(USE_MPI)

# Set verbosity of the Makefile according to option
IF(VERBOSE)
  SET(CMAKE_VERBOSE_MAKEFILE ON)
ELSE(VERBOSE)
  SET(CMAKE_VERBOSE_MAKEFILE OFF)
ENDIF(VERBOSE)

# This executes code that sets the compile flags for DEBUG, RELEASE, and TESTING.
INCLUDE(${CMAKE_MODULE_PATH}/SetFortranFlags.cmake)


#Check for .git and extract the current SHA1 revision.
#create the current scifor_version.inc file
IF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/.git)
  FIND_PACKAGE(Git)
  IF(GIT_FOUND)
    EXECUTE_PROCESS(
      COMMAND ${GIT_EXECUTABLE} rev-parse HEAD
      WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
      OUTPUT_VARIABLE GIT_SHA1
      ERROR_QUIET
      OUTPUT_STRIP_TRAILING_WHITESPACE)
    MESSAGE( STATUS "${Yellow}Git version: ${ColourReset}${GIT_SHA1}" )
  ELSE(GIT_FOUND)
    SET(GIT_SHA1 0)
  ENDIF(GIT_FOUND)
ENDIF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/.git)
SET(SF_VERSION_FILE ${CMAKE_CURRENT_SOURCE_DIR}/src/${PROJECT_NAME}_version.inc)
FILE(WRITE  ${SF_VERSION_FILE}
  "character(len=41),parameter,public :: ${PROJECT_NAME}_version_sha1 = \"${GIT_SHA1}\"\n")


#set MPI preprocessing defition:
IF(USE_MPI)
  ADD_DEFINITIONS(-D_MPI)
ELSE(USE_MPI)
  ADD_DEFINITIONS(-D_)
ENDIF(USE_MPI)



############################################################
# Define the actual files and folders that make up the build
############################################################
SET(USER_HOME $ENV{HOME})
SET(USER $ENV{USER})


#make sure FC_PLAT is lowecase
STRING(TOLOWER "${CMAKE_Fortran_COMPILER_ID}" FC_PLAT)

SET(PREFIX  "$ENV{HOME}/opt/${PROJECT_NAME}/${VERSION}/${FC_PLAT}" CACHE PATH "Prefix prepended to install directories")

SET(CMAKE_INSTALL_PREFIX "${PREFIX}" CACHE INTERNAL "Prefix prepended to install directories" FORCE)

# Define the library name
SET(SCIFORLIB scifor)

# Define some directories
SET(SF_SRC ${CMAKE_SOURCE_DIR}/src)
SET(SF_ETC ${CMAKE_SOURCE_DIR}/etc)
SET(SF_ENV ${CMAKE_SOURCE_DIR}/etc/environment_modules)
SET(SF_BIN ${CMAKE_SOURCE_DIR}/bin)
SET(SF_TMP_INC ${CMAKE_BINARY_DIR}/include)
SET(SF_TMP_ETC ${CMAKE_BINARY_DIR}/etc)
SET(SF_TMP_BIN ${CMAKE_BINARY_DIR}/bin)
SET(SF_TARGET_LIB ${CMAKE_INSTALL_PREFIX}/lib)
SET(SF_TARGET_INC ${CMAKE_INSTALL_PREFIX}/include)
SET(SF_TARGET_ETC ${CMAKE_INSTALL_PREFIX}/etc)
SET(SF_TARGET_BIN ${CMAKE_INSTALL_PREFIX}/bin)

# Have the .mod files placed in the INC folder
SET(CMAKE_Fortran_MODULE_DIRECTORY ${SF_TMP_INC})
INCLUDE_DIRECTORIES(BEFORE ${CMAKE_Fortran_MODULE_DIRECTORY})



SET(SRC_DIR_ARPACK ${SF_SRC}/arpack)
ADD_SUBDIRECTORY(${SRC_DIR_ARPACK})


SET(SRC_DIR_BLAS ${SF_SRC}/blas)
ADD_SUBDIRECTORY(${SRC_DIR_BLAS})


SET(SRC_DIR_FFTPACK ${SF_SRC}/fftpack)
ADD_SUBDIRECTORY(${SRC_DIR_FFTPACK})


SET(SRC_DIR_LAPACK ${SF_SRC}/lapack)
ADD_SUBDIRECTORY(${SRC_DIR_LAPACK})


SET(SRC_DIR_MINPACK ${SF_SRC}/minpack)
ADD_SUBDIRECTORY(${SRC_DIR_MINPACK})


SET(SRC_DIR_QUADPACK ${SF_SRC}/quadpack)
ADD_SUBDIRECTORY(${SRC_DIR_QUADPACK})


SET(SRC_DIR_SF_INIT ${SF_SRC}/SF_INIT)
ADD_SUBDIRECTORY(${SRC_DIR_SF_INIT})


SET(SRC_DIR_SF_MPI ${SF_SRC}/SF_MPI)
ADD_SUBDIRECTORY(${SRC_DIR_SF_MPI})


SET(SRC_DIR_SF_IOTOOLS ${SF_SRC}/SF_IOTOOLS)
ADD_SUBDIRECTORY(${SRC_DIR_SF_IOTOOLS})


SET(SRC_DIR_SF_FFT ${SF_SRC}/SF_FFT)
ADD_SUBDIRECTORY(${SRC_DIR_SF_FFT})


SET(SRC_DIR_SF_DERIVATE ${SF_SRC}/SF_DERIVATE)
ADD_SUBDIRECTORY(${SRC_DIR_SF_DERIVATE})


SET(SRC_DIR_SF_OPTIMIZE ${SF_SRC}/SF_OPTIMIZE)
ADD_SUBDIRECTORY(${SRC_DIR_SF_OPTIMIZE})


SET(SRC_DIR_SF_SPECIAL ${SF_SRC}/SF_SPECIAL)
ADD_SUBDIRECTORY(${SRC_DIR_SF_SPECIAL})


SET(SRC_DIR_SF_INTEGRATE ${SF_SRC}/SF_INTEGRATE)
ADD_SUBDIRECTORY(${SRC_DIR_SF_INTEGRATE})


SET(SRC_DIR_SF_INTERPOLATE ${SF_SRC}/SF_INTERPOLATE)
ADD_SUBDIRECTORY(${SRC_DIR_SF_INTERPOLATE})


SET(SRC_DIR_SF_RANDOM ${SF_SRC}/SF_RANDOM)
ADD_SUBDIRECTORY(${SRC_DIR_SF_RANDOM})


SET(SRC_DIR_SF_LINALG ${SF_SRC}/SF_LINALG)
ADD_SUBDIRECTORY(${SRC_DIR_SF_LINALG})

SET(SRC_DIR_SF_SP_LINALG ${SF_SRC}/SF_SP_LINALG)
ADD_SUBDIRECTORY(${SRC_DIR_SF_SP_LINALG})

SET(SRC_DIR_SF_PARSE_INPUT ${SF_SRC}/SF_PARSE_INPUT)
ADD_SUBDIRECTORY(${SRC_DIR_SF_PARSE_INPUT})

ADD_SUBDIRECTORY(${SF_SRC})

# # Build the scifor library and have it placed in the target lib folder
ADD_LIBRARY(scifor
  $<TARGET_OBJECTS:ARPACKLIB>
  $<TARGET_OBJECTS:BLASLIB>
  $<TARGET_OBJECTS:LAPACKLIB>
  $<TARGET_OBJECTS:FFTPACKLIB>
  $<TARGET_OBJECTS:MINPACKLIB>
  $<TARGET_OBJECTS:QUADPACKLIB>
  $<TARGET_OBJECTS:SF_INITLIB>
  $<TARGET_OBJECTS:SF_MPILIB>
  $<TARGET_OBJECTS:SF_IOTOOLSLIB>
  $<TARGET_OBJECTS:SF_FFTLIB>
  $<TARGET_OBJECTS:SF_DERIVATELIB>
  $<TARGET_OBJECTS:SF_OPTIMIZELIB>
  $<TARGET_OBJECTS:SF_SPECIALLIB>  
  $<TARGET_OBJECTS:SF_INTEGRATELIB>
  $<TARGET_OBJECTS:SF_INTERPOLATELIB>
  $<TARGET_OBJECTS:SF_RANDOMLIB>
  $<TARGET_OBJECTS:SF_LINALGLIB>
  $<TARGET_OBJECTS:SF_SP_LINALGLIB>
  $<TARGET_OBJECTS:SF_PARSE_INPUTLIB>
  $<TARGET_OBJECTS:SCIFORLIB>
  )


ADD_DEPENDENCIES(SCIFORLIB
  SF_INITLIB
  SF_MPILIB
  SF_IOTOOLSLIB
  SF_FFTLIB
  SF_DERIVATELIB
  SF_OPTIMIZELIB
  SF_SPECIALLIB 
  SF_INTEGRATELIB
  SF_INTERPOLATELIB
  SF_RANDOMLIB
  SF_LINALGLIB
  SF_SP_LINALGLIB
  SF_PARSE_INPUTLIB
  )


# Add a distclean target to the Makefile
ADD_CUSTOM_TARGET(distclean 
    COMMAND ${CMAKE_COMMAND} -P ${CMAKE_SOURCE_DIR}/distclean.cmake
)




SET(PERMISSION_777
  OWNER_WRITE OWNER_READ OWNER_EXECUTE
  GROUP_WRITE GROUP_READ GROUP_EXECUTE
  WORLD_WRITE WORLD_READ WORLD_EXECUTE)




INCLUDE(${CMAKE_MODULE_PATH}/PostBuildScifor.cmake)

SET(TMP_ENV_MODULE_FILE ${SF_TMP_ETC}/modules/${PROJECT_NAME}/${FC_PLAT})
BUILD_ENV_MODULE(${TMP_ENV_MODULE_FILE})

SET(TMP_CONFIGVARS_FILE ${SF_TMP_BIN}/configvars.sh)
BUILD_CONFIGVARS(${TMP_CONFIGVARS_FILE})

SET(TMP_PKCONFIG_FILE ${SF_TMP_ETC}/${PROJECT_NAME}.pc)
BUILD_PKCONFIG(${TMP_PKCONFIG_FILE})

INSTALL(DIRECTORY ${CMAKE_Fortran_MODULE_DIRECTORY}/ DESTINATION ${SF_TARGET_INC})

INSTALL(TARGETS scifor DESTINATION ${SF_TARGET_LIB})

INSTALL(DIRECTORY ${SF_TMP_ETC}/ DESTINATION ${SF_TARGET_ETC})

INSTALL(FILES ${SF_BIN}/scifor_completion.sh DESTINATION ${SF_TARGET_BIN}/
  PERMISSIONS ${PERMISSION_777} SETUID)

INSTALL(FILES ${TMP_CONFIGVARS_FILE} DESTINATION ${SF_TARGET_BIN}/
  PERMISSIONS ${PERMISSION_777} SETUID)




MESSAGE( STATUS "${Yellow}To conclude installation:${ColourReset} 
$ make
$ make install
$ make post-install
")


ADD_CUSTOM_TARGET(
  post-install
  COMMAND "${CMAKE_COMMAND}" -P ${CMAKE_MODULE_PATH}/HomeInstall.cmake ${CMAKE_SOURCE_DIR} ${CMAKE_INSTALL_PREFIX} ${PROJECT_NAME}
  WORKING_DIRECTORY
  "${CMAKE_BINARY_DIR}"
)





